package cn.tedu.submarine;
import javax.swing.JFrame;
import javax.swing.JPanel;
import java.awt.*;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

public class World extends JPanel{
    public static final int WIDTH =641;
    public static final int HEIGHT =479;

    public static final int RUNNING = 0;
    public static final int PAUSE = 1;
    public static final int GAME_OVER = 2;
    private int state = RUNNING;


    private BattleShip ship = new BattleShip();
    private SeaObject [] submarines ={};
    private Mine [] mines ={};
    private Bomb [] bombs ={};
    private Bomb2[] bomb2s = {};
    private Tor[] tors = {};
    private Plane[] planes = {};
    private Missile[] missiles = {};
    private NuclearBomb[] nuclearBombs = {};
    //生成潜艇
    private SeaObject nextSubmarine(){
        Random rand = new Random(); //随机数对象
        int type = rand.nextInt(30); //0到24
        if(type<10){ //0到9时，返回侦察潜艇
            return new ObserveSubmarine();
        }else if(type<16){ //10到15时，返回鱼雷潜艇
            return new TorpedoSubmarine();
        }else if (type<20){ //16到19时，返回水雷  潜艇
            return new MineSubmarine();
        }else if (type<25 && score>=50){
            return new TySub();
        }else if (type<30){
            return new Plane(641,rand.nextInt(100));
        }
        return new ObserveSubmarine();
    }

    private int submarineEnterIndex = 0;
    /** 潜艇(侦察潜艇、鱼雷潜艇、水雷潜艇)入场 */
    private void submarineEnterAction(){
        submarineEnterIndex++;
        if (submarineEnterIndex%40==0){
            SeaObject obj = nextSubmarine();
            submarines = Arrays.copyOf(submarines,submarines.length+1);
            submarines[submarines.length-1] = obj;
        }
    }



    private int mineEnterIndex = 0;
    /** 水雷入场 */
    public void mineEnterAction(){
        mineEnterIndex++;
        if (mineEnterIndex%100==0){
            for (int i = 0;i<submarines.length;i++){
                if (submarines[i] instanceof MineSubmarine){
                    MineSubmarine ms = (MineSubmarine)submarines[i];
                    Mine obj =ms.shootMine();
                    mines = Arrays.copyOf(mines,mines.length+1);
                    mines[mines.length-1] = obj;

                }
            }
        }
    }

    private int torEnterIndex = 0;
    /** 鱼雷入场 */
    public void torEnterAction(){
        torEnterIndex++;
        if (torEnterIndex%300==0){
            for (int i = 0;i<submarines.length;i++){
                if (submarines[i] instanceof TySub){
                    TySub ts = (TySub)submarines[i];
                    Tor obj =ts.shootTor();
                    tors = Arrays.copyOf(tors,tors.length+1);
                    tors[tors.length-1] = obj;

                }
            }
        }
    }





    /**飞机炸弹入场*/
    private int missileEnterIndex = 0;

    public void missileEnterAction(){
        missileEnterIndex++;
        if (missileEnterIndex%50==0){
            for (int i = 0;i<submarines.length;i++){
                if (submarines[i] instanceof Plane){
                    Plane ple = (Plane)submarines[i];
                    Missile mi = ple.shootMissile();
                    missiles = Arrays.copyOf(missiles,missiles.length+1);
                    missiles[missiles.length-1]=mi;
                }
            }
        }
    }



    /**海洋对象移动*/
    private void moveAction(){
        for (int i = 0;i<submarines.length;i++){
            submarines[i].move();
        }
        for (int i =0 ; i<mines.length;i++){
            mines[i].move();
        }
        for (int i =0;i< bombs.length;i++){
            bombs[i].move();
        }
        for (int i =0;i< bomb2s.length;i++){
            bomb2s[i].move();
        }
        for (int i = 0;i<tors.length;i++){
            tors[i].move();
        }
        for (int i = 0;i<missiles.length;i++){
            missiles[i].move();
        }
        for (int i = 0;i<nuclearBombs.length;i++){
            nuclearBombs[i].move();
        }

    }
    /** 删除越界的海洋对象-----避免内存泄漏 */
    private void outOfBoundsAction(){ //每10毫秒走一次
        for(int i=0;i<submarines.length;i++){ //遍历所有潜艇
            if(submarines[i].isOutOfBounds() || submarines[i].isDead()){ //若越界了，或者，是DEAD状态的
                submarines[i] = submarines[submarines.length-1]; //将越界元素替换为最后一个元素
                submarines = Arrays.copyOf(submarines,submarines.length-1); //缩容
            }
        }

        for(int i=0;i<mines.length;i++){ //遍历所有水雷
            if(mines[i].isOutOfBounds() || mines[i].isDead()){ //若越界了，或者，是DEAD状态的
                mines[i] = mines[mines.length-1]; //将越界元素替换为最后一个元素
                mines = Arrays.copyOf(mines,mines.length-1); //缩容
            }
        }

        for(int i=0;i<bombs.length;i++){ //遍历所有炸弹
            if(bombs[i].isOutOfBounds() || bombs[i].isDead()){ //若越界了，或者，是DEAD状态的
                bombs[i] = bombs[bombs.length-1]; //将越界元素替换为最后一个元素
                bombs = Arrays.copyOf(bombs,bombs.length-1); //缩容
            }
        }
        for(int i=0;i<bomb2s.length;i++){ //遍历所有炸弹
            if(bomb2s[i].isOutOfBounds() || bomb2s[i].isDead()){ //若越界了，或者，是DEAD状态的
                bomb2s[i] = bomb2s[bomb2s.length-1]; //将越界元素替换为最后一个元素
                bomb2s = Arrays.copyOf(bomb2s,bomb2s.length-1); //缩容
            }
        }
        for(int i=0;i<tors.length;i++){ //遍历所有炸弹
            if(tors[i].isOutOfBounds() || tors[i].isDead()){ //若越界了，或者，是DEAD状态的
                tors[i] = tors[tors.length-1]; //将越界元素替换为最后一个元素
                tors = Arrays.copyOf(tors,tors.length-1); //缩容
            }
        }
        for(int i=0;i<missiles.length;i++){ //遍历所有炸弹
            if(missiles[i].isOutOfBounds() || missiles[i].isDead()){ //若越界了，或者，是DEAD状态的
                missiles[i] = missiles[missiles.length-1]; //将越界元素替换为最后一个元素
                missiles = Arrays.copyOf(missiles,missiles.length-1); //缩容
            }
        }
        for(int i=0;i<nuclearBombs.length;i++){ //遍历所有炸弹
            if(nuclearBombs[i].isOutOfBounds() || nuclearBombs[i].isDead()){ //若越界了，或者，是DEAD状态的
                nuclearBombs[i] = nuclearBombs[nuclearBombs.length-1]; //将越界元素替换为最后一个元素
                nuclearBombs = Arrays.copyOf(nuclearBombs,nuclearBombs.length-1); //缩容
            }
        }


    }

    public int score = 0; //玩家的得分
    /** 炸弹与潜艇的碰撞 */
    private void bombBangAction(){ //每10毫秒走一次
        for(int i=0;i<bombs.length;i++){ //遍历所有炸弹
            Bomb b = bombs[i]; //获取每个炸弹
            for(int j=0;j<submarines.length;j++){ //遍历所有潜艇
                SeaObject s = submarines[j]; //获取每个潜艇
                if(b.isLive() && s.isLive() && s.isHit(b)){ //若都活着并且还撞上了
                    s.goDead(); //潜艇去死
                    b.goDead(); //炸弹去死
                    if(s instanceof EnemyScore){ //若被撞潜艇是分
                        EnemyScore es = (EnemyScore)s; //将被撞潜艇强转为分的接口
                        score += es.getScore(); //玩家得分
                    }
                    if(s instanceof EnemyLife){ //若被撞潜艇是命
                        EnemyLife el = (EnemyLife)s; //将被撞潜艇强转为命的接口
                        int num = el.getLife(); //获取命数
                        ship.addLife(num); //战舰增命
                    }
                }
            }
        }

    }
    private void bomb2BangAction(){ //每10毫秒走一次
        for(int i=0;i<bomb2s.length;i++){ //遍历所有炸弹
            Bomb2 b = bomb2s[i]; //获取每个炸弹
            for(int j=0;j<submarines.length;j++){ //遍历所有潜艇
                SeaObject s = submarines[j]; //获取每个潜艇
                if(b.isLive() && s.isLive() && s.isHit(b)){ //若都活着并且还撞上了
                    s.goDead(); //潜艇去死
                    b.goDead(); //炸弹去死
                    if(s instanceof EnemyScore){ //若被撞潜艇是分
                        EnemyScore es = (EnemyScore)s; //将被撞潜艇强转为分的接口
                        score += es.getScore(); //玩家得分
                    }
                    if(s instanceof EnemyLife){ //若被撞潜艇是命
                        EnemyLife el = (EnemyLife)s; //将被撞潜艇强转为命的接口
                        int num = el.getLife(); //获取命数
                        ship.addLife(num); //战舰增命
                    }
                }
            }
        }

    }

    private void nuclearbombBangAction(){ //每10毫秒走一次
        for(int i=0;i<nuclearBombs.length;i++){ //遍历所有炸弹
            NuclearBomb b = nuclearBombs[i]; //获取每个炸弹
            for(int j=0;j<submarines.length;j++){ //遍历所有潜艇
                SeaObject s = submarines[j]; //获取每个潜艇
                if(b.isLive() && s.isLive() && s.isHit(b)){ //若都活着并且还撞上了
                    s.goDead(); //潜艇去死
                    b.goDead(); //炸弹去死
                    if(s instanceof EnemyScore){ //若被撞潜艇是分
                        EnemyScore es = (EnemyScore)s; //将被撞潜艇强转为分的接口
                        score += es.getScore(); //玩家得分
                    }
                    if(s instanceof EnemyLife){ //若被撞潜艇是命
                        EnemyLife el = (EnemyLife)s; //将被撞潜艇强转为命的接口
                        int num = el.getLife(); //获取命数
                        ship.addLife(num); //战舰增命
                    }
                }
            }
        }

    }


    public void mineBangAction(){
        for (int i = 0;i<mines.length;i++){
            Mine m = mines[i];
            if (m.isLive() && ship.isLive() && m.isHit(ship)){
                m.goDead();
                ship.subtractLife();
            }
        }
    }
    public void torBangAction(){
        for (int i = 0;i<tors.length;i++){
            Tor t = tors[i];
            if (t.isLive() && ship.isLive() && t.isHit(ship)){
                t.goDead();
                ship.subtractLife2();
            }
        }
    }
    public void missileBangAction(){
        for (int i = 0;i<missiles.length;i++){
            Missile t = missiles[i];
            if (t.isLive() && ship.isLive() && t.isHit(ship)){
                t.goDead();
                ship.subtractLife();
            }
        }
    }




    private void checkGameOverAction(){
        if (ship.getLife()<=0){
            state = GAME_OVER;
        }
    }

    private void action(){
        KeyAdapter k = new KeyAdapter(){
            /** 重写keyReleased()按键抬起事件 */
            public void keyReleased(KeyEvent e) { //不要求掌握---当按键抬起时会自动触发
                if(e.getKeyCode()==KeyEvent.VK_P){ //不要求掌握---若抬起的是P键
                    if(state==RUNNING){ //运行状态时修改为暂停状态
                        state = PAUSE;
                    }else if(state==PAUSE){ //暂停状态时修改为运行状态
                        state = RUNNING;
                    }
                }

                if(state==RUNNING){ //仅有运行状态时执行
                    if(e.getKeyCode()==KeyEvent.VK_SPACE){ //不要求掌握---若抬起的是空格键
                        Bomb obj = ship.shootBomb(); //获取炸弹对象
                        bombs = Arrays.copyOf(bombs,bombs.length+1); //扩容
                        bombs[bombs.length-1] = obj; //将obj添加到最后一个元素上

                    }
                    if (score>=50){
                        if(e.getKeyCode()==KeyEvent.VK_SPACE){ //不要求掌握---若抬起的是空格键
                            Bomb2 obj = ship.shootBomb2(); //获取炸弹对象
                            bomb2s = Arrays.copyOf(bomb2s,bomb2s.length+1); //扩容
                            bomb2s[bomb2s.length-1] = obj; //将obj添加到最后一个元素上

                        }
                    }
                    if(e.getKeyCode()==KeyEvent.VK_LEFT){ //不要求掌握---若抬起的是左箭头
                        ship.moveLeft(); //战舰左移
                    }
                    if(e.getKeyCode()==KeyEvent.VK_RIGHT){ //不要求掌握---若抬起的是右箭头
                        ship.moveRight(); //战舰右移
                    }
                    if(e.getKeyCode()==KeyEvent.VK_Z){ //不要求掌握---若抬起的是空格键
                        NuclearBomb obj = ship.shootn(); //获取炸弹对象
                        nuclearBombs = Arrays.copyOf(nuclearBombs,nuclearBombs.length+1); //扩容
                        nuclearBombs[nuclearBombs.length-1] = obj; //将obj添加到最后一个元素上

                    }
                }
            }

        };
        this.addKeyListener(k); //添加侦听器----不要求掌握

        Timer timer = new Timer(); //定时器对象
        int interval = 10; //定时间隔(以毫秒为单位)
        timer.schedule(new TimerTask() {
            public void run() { //定时干的事---每10毫秒自动执行
                if(state==RUNNING){ //仅在运行状态时执行
                    submarineEnterAction(); //潜艇入场
                    mineEnterAction();      //水雷入场
                    moveAction();           //海洋对象移动
                    outOfBoundsAction();    //删除越界的海洋对象
                    bombBangAction();       //炸弹与潜艇的碰撞
                    bomb2BangAction();
                    mineBangAction();       //水雷与战舰的碰撞
                    torEnterAction();
                    torBangAction();
                    missileEnterAction();
                    missileBangAction();
                    nuclearbombBangAction();

                    checkGameOverAction();  //检测游戏结束


                    repaint(); //重画(重新调用paint()方法)-----不需要掌握
                }
            }
        }, interval, interval); //定时计划表
    }



    public void paint(Graphics g){
        Images.sea.paintIcon(null,g,0,0);
        ship.paintImage(g);
        for (int i =0;i<submarines.length;i++){
            submarines[i].paintImage(g);
        }
        for (int i = 0; i<mines.length;i++){
            mines[i].paintImage(g);
        }
        for (int i =0 ; i< bombs.length;i++){
            bombs[i].paintImage(g);
        }
        for (int i =0 ; i< bomb2s.length;i++){
            bomb2s[i].paintImage(g);
        }
        for (int i =0 ; i< tors.length;i++){
            tors[i].paintImage(g);
        }
        for (int i =0 ; i< planes.length;i++){
            planes[i].paintImage(g);
        }
        for (int i =0 ; i< missiles.length;i++){
            missiles[i].paintImage(g);
        }
        for (int i =0 ; i< nuclearBombs.length;i++){
            nuclearBombs[i].paintImage(g);
        }

        g.drawString("SCORE: "+score,200,50);
        g.drawString("LIFE: "+ship.getLife(),400,50);

        if(state==GAME_OVER){ //游戏结束状态时，画游戏结束图
            Images.gameover.paintIcon(null,g,0,0);
            g.drawString("您的得分"+score,300,250);
        }
    }


    public static void main(String[] args) {
        JFrame frame = new JFrame(); //3.
        World world = new World(); //会创建上面的那一堆对象
        world.setFocusable(true);
        frame.add(world);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(WIDTH+6, HEIGHT+28);
        frame.setLocationRelativeTo(null);
        frame.setResizable(false);
        frame.setVisible(true); //自动调用paint()方法
        world.action();

    }
}
